package com.wowangz.cms.syscore.autotask.job;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.Map;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.ibatis.session.SqlSession;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.wowangz.cms.common.utils.SysConstant;
import com.wowangz.cms.syscore.InitEnvironment;
import com.wowangz.cms.syscore.SqlSessionContainer;
import com.wowangz.cms.syscore.autotask.manager.AutoTaskRunManager;
import com.wowangz.cms.syscore.autotask.pojo.Autotask;
import com.wowangz.cms.syscore.autotask.pojo.Autotaskresult;
import com.wowangz.cms.syscore.utils.SpringUtil;
import com.wowangz.cms.syscore.utils.SystemConfig;

/**
 * @author Administrator 
 * 自动任务基类
 */
public abstract class BaseJob implements Job
{

	private static Logger		log				= LoggerFactory.getLogger(BaseJob.class);

	//add by yoyo 获取配置的运行自动任务服务名
	private static SystemConfig systemConfig=new SystemConfig("autoTaskRunServer");
	private static Map systemConfigMap = systemConfig.getKeyValueMap();

	/**
	 * 自动任务执行前预处理操作
	 * 
	 * @param context
	 * @throws JobExecutionException
	 */
	public void beforeExecute(JobExecutionContext context) throws Exception
	{
		DriverManagerDataSource dataSource = (DriverManagerDataSource)SpringUtil.getBean("publicDataSource"); 
		SqlSession sqlsession = InitEnvironment.getSqlSessionFactory().openSession(dataSource,true);
		try
		{
			Autotask task = getAutotaskByContext(context);
			// 检查修改并保存任务状态
			if ((task.getExecutestatus().longValue() == SysConstant.ExecuteStatus.RUN))
			{
				throw new Exception(MessageFormat.format("自动任务[id={0},name={1}]正在运行!",new Object[]{task.getId(),task.getName()}));
			}
			else{
				task.setExecutestatus(SysConstant.ExecuteStatus.RUN);
				// 保存任务新状态
				sqlsession.update("Autotask.updatetask_executestatus",task);
			}
		}catch(Exception e)
		{
			e.printStackTrace();
			throw e;
		}finally
		{
			if (sqlsession!=null) {
				sqlsession.close();
			}
		}
	}

	/**
	 * 根据自动任务上下文信息获得当前自动任务实例
	 * @param context
	 * @return
	 * @throws Exception
	 */
	public Autotask getAutotaskByContext(JobExecutionContext context) throws Exception
	{
		DriverManagerDataSource dataSource = (DriverManagerDataSource)SpringUtil.getBean("publicDataSource"); 
		SqlSession sqlsession = InitEnvironment.getSqlSessionFactory().openSession(dataSource,true);
		Autotask task = null;
		try{
			JobDetail job = context.getJobDetail();
			Long taskID = (Long) job.getJobDataMap().get(AutoTaskRunManager.KEY_AUTOTASK);
			task = sqlsession.selectOne("Autotask.getAutoTaskByID",taskID);
		}catch(Exception e)
		{
			e.printStackTrace();
			throw e;
		}finally
		{
			if (sqlsession!=null) {
				sqlsession.close();
			}
		}
		return task;
	}

	/**
	 * 自动任务执行后操作
	 * 保存任务执行结果
	 * @param context
	 * @param message
	 * @throws JobExecutionException
	 */
	public void afterExecute(JobExecutionContext context, String message,Timestamp startTime)
	{
		DriverManagerDataSource dataSource = (DriverManagerDataSource)SpringUtil.getBean("publicDataSource"); 
		SqlSession sqlsession = InitEnvironment.getSqlSessionFactory().openSession(dataSource,true);

		Autotask task = null;
		Autotaskresult result = new Autotaskresult();
		try
		{
			// 获取当前任务项
			task = getAutotaskByContext(context);
			result.setTaskid(task.getId());
			result.setStarttime(startTime);
			result.setEndtime(new Timestamp(System.currentTimeMillis()));
			result.setResult(message);
			//保存运行的服务器名
			result.setServername((String)systemConfigMap.get("servername"));
			// 修改任务状态
			if (task.getExecutestatus().longValue() == SysConstant.ExecuteStatus.RUN)
			{
				task.setExecutestatus(new Long(SysConstant.ExecuteStatus.STOP)); // 任务完成标志
				// 保存任务新状态
				sqlsession.update("Autotask.updatetask_executestatus",task);
			}
		}
		catch (Exception e)
		{
			if(task != null)
			{
				message = "修改任务(" + task.getId() + ")的执行状态失败，你必须手工修改任务的执行状态!";
			}
			log.info(message);
			e.printStackTrace();
			result.setResult(message);
		}
		try
		{
			sqlsession.insert("Autotask.insertResultRecord", result);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}finally
		{
			if (sqlsession!=null) {
				sqlsession.close();
			}
			SqlSessionContainer sqlSessionContainer = new SqlSessionContainer();
			sqlSessionContainer.closeSqlSession();
		}
	}

	/**
	 * 自动任务核心操作 所有自动任务必须实现该方法
	 * 
	 * @param context
	 * @throws JobExecutionException
	 * @throws Exception
	 */
	public abstract void innerExecute(JobExecutionContext context) throws Exception;

	/**
	 * 自动任务执行入口
	 * @param context
	 * @throws JobExecutionException
	 */
	public final void execute(JobExecutionContext context) throws JobExecutionException
	{
		String message = "执行成功";
		Timestamp startTime=null;
		try{
			startTime=new Timestamp(System.currentTimeMillis());
			beforeExecute(context);
		}catch(Exception e){
			log.info("自动任务运行前校验异常："+e.getMessage());
			return;
		}
		try
		{
			innerExecute(context);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
			message = "执行失败:" + ex.getMessage();
			log.info("执行失败:" + ex.getMessage());
		}
		finally
		{
			afterExecute(context, message,startTime);
		}
	}
	
	public void sendTransDataToMq(String json,String queue) {

		ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, systemConfigMap.get("mq_queue").toString());
		Connection connection = null;
		Session session = null;
		try {
			long starttime = System.currentTimeMillis();
			connection = factory.createConnection();
			connection.start();
			session = connection.createSession(Boolean.FALSE,
					Session.AUTO_ACKNOWLEDGE);
			Destination destination = session.createQueue(queue);
			MessageProducer producer = session.createProducer(destination);
			producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
			ObjectMessage message = session.createObjectMessage(json);
			producer.send(message);
			long endtime = System.currentTimeMillis();
			System.out.println(endtime - starttime);

		} catch (JMSException e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				try {
					session.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
